import tensorflow as tf
import Core.functions as functions
import Core.dataset as dataset
import Core.Model as Model
from tensorflow.keras.optimizers import Adam
import numpy as np

# 开始算法
# 设置算法结束为迭代一千次
'''
参数说明:
n: 种群数量, 设置为8
cross_point: 交叉点, 设置为6(交叉前6位)
cross_rate: 交叉率, 设置为0.7
mutation_rate: 变异率, 设置为0.1
'''

n = 8
cross_point = 6
cross_rate = 0.7
mutation_rate = 0.1

# 1.拿到数据集
X_train, y_train, X_test, y_test = dataset.get_datasets()
# print(X_train, y_train, X_test, y_test)

# 2.初始化种群
# 此处是一个三维的矩阵(这里其实只需要数据集的'维度')
all_pop_weights = functions.init_matrix(n, X_train)
for i in range(1000):
    # 3.拿到适应度数组
    accuracy = functions.fitness(all_pop_weights, X_train, y_train)
    # 4.种群编码
    # 编码后的种群数组为p_gene
    p_gene = functions.encode(all_pop_weights)

    # 5.选择操作
    p_choice = functions.choice(p_gene, accuracy)

    # 6.交叉操作
    p_cross = functions.cross(p_choice, cross_point, cross_rate)

    # 7.变异操作
    p_mutation = functions.mutation(p_cross, mutation_rate)

    # 8.解码操作(方便开始下一轮迭代)
    all_pop_weights = functions.decode(p_mutation, all_pop_weights)

# GA结束后选出适应度分数最高的个体
index = np.argmax(accuracy)
# 将参数矩阵分别写入两个矩阵中, 作为ANN的初始参数
my_mat_1 = all_pop_weights[index][0]
my_mat_2 = all_pop_weights[index][1]
model = Model.get_model(my_mat_1, my_mat_2)
model.summary()

# 配置训练器
model.compile(loss='binary_crossentropy', optimizer=Adam(lr=1e-4), metrics=['acc'])
# 训练
model.fit(X_train, y_train, batch_size=32, epochs=5, validation_data=(X_test, y_test), validation_freq=1)